package com.yonyou.brigade.third_parties.ystrip.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.yonyou.brigade.basic_init.enums.ChannelEnum;
import com.yonyou.brigade.order_center.model.BriTrainOrder;
import com.yonyou.brigade.order_center.service.IBriOrderService;
import com.yonyou.brigade.order_center.service.IBriTrainOrderService;
import com.yonyou.brigade.third_parties.ystrip.constant.YStripConstant;
import com.yonyou.brigade.third_parties.ystrip.core.YStripBase;
import com.yonyou.brigade.third_parties.ystrip.model.YStripSyncOrderParam;
import com.yonyou.brigade.third_parties.ystrip.model.YStripUser;
import com.yonyou.brigade.third_parties.ystrip.model.YstripUserHistory;
import com.yonyou.brigade.third_parties.ystrip.service.IYStripPublicService;
import com.yonyou.brigade.third_parties.ystrip.service.IYstripUserHistoryService;
import com.yonyou.brigade.third_parties.ystrip.utils.OrderConvertUtil;
import com.yonyou.brigade.ybz.service.IConvertService;
import com.yonyou.ybzboot.starter.common.cipher.SHAUtil;
import com.yonyou.ybzboot.starter.common.cipher.SHAUtil.*;
import com.yonyou.ybzboot.starter.common.exception.BaseException;
import com.yonyou.ybzboot.starter.mongodb.dao.IMongoDao;
import com.yonyou.ybzboot.starter.mongodb.model.CriteriaMap;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class YStripPublicServiceImpl implements IYStripPublicService {

    private static Logger logger = LoggerFactory.getLogger(YStripPublicServiceImpl.class);

    @Autowired
    YStripBase yStripBase;

    @Value("${ystrip.tradeTrainType}")
    private String ystripTradeType;

    @Value("${cnv.baigade.system.code}")
    private String systemCode;

    @Value("${cnv.register.userId}")
    private String cnvRegisterUserId;

    @Value("${cnv.register.tenant}")
    private String cnvRegisterTenant;

    @Value("${cnv.register.cookie}")
    private String cnvRegisterCookie;

    @Autowired
    @Qualifier("ystripUserHistoryServiceImpl")
    IYstripUserHistoryService iYstripUserHistoryService;

    @Autowired
    @Qualifier("briTrainOrderServiceImpl")
    private IBriTrainOrderService briTrainOrderService;

    @Autowired
    @Qualifier("convertServiceImpl")
    private IConvertService convertService;

    @Autowired
    @Qualifier("briOrderServiceImpl")
    private IBriOrderService briOrderService;

    @Autowired
    private IMongoDao mongoDao;

    @Override
    public String insertUser(List<YStripUser> yStripUsers) {
        JSONObject reqJSON = new JSONObject();
        reqJSON.put("Channel", YStripConstant.CHANNEL);
        reqJSON.put("action",YStripConstant.USER_INSERT_ACTION);
        reqJSON.put("times",String.valueOf((int)(System.currentTimeMillis()/1000)));
        JSONArray userArray = new JSONArray();
        Map<String,String> companyNoUserNo2UserIdMap = new HashMap<>();
        yStripUsers.forEach((yStripUser)->{
            JSONObject singleUser = new JSONObject();
            singleUser.put("CompanyNo",yStripUser.getCompanyNo());
            singleUser.put("UserNo",yStripUser.getUserNo());
            singleUser.put("UserName",yStripUser.getUserName());
            singleUser.put("UserPhone",yStripUser.getUserPhone());
            singleUser.put("UserEmail",yStripUser.getUserEmail());
            singleUser.put("CardNo",yStripUser.getCardNo());
            singleUser.put("Remark",yStripUser.getRemark());
            userArray.add(singleUser);
            companyNoUserNo2UserIdMap.put(yStripUser.getCompanyNo() + yStripUser.getUserNo(),
                    yStripUser.getUserId());
        });
        reqJSON.put("userList",userArray);

        String sign = SHAUtil.getMD5(reqJSON.getString("Channel") + reqJSON.getString("action")
                    + reqJSON.getString("times") + userArray.toJSONString() + yStripBase.getKey());

        reqJSON.put("sign",sign);
        String reqStr = reqJSON.toJSONString();
        logger.info("云上火车票，新增用户，请求数据->" + reqStr);
        String respStr = "{}";
        try {
            respStr = Request.Post(yStripBase.getBaseUrl() + yStripBase.getUserMethod())
                    .bodyString(reqStr,ContentType.APPLICATION_JSON)
                    .execute().returnContent().asString(Charset.forName("UTF-8"));
            logger.info("云上火车票，新增用户，返回值->" + respStr);
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
            throw new BaseException(-100,e.getMessage());
        }

        JSONObject returnJSON = JSON.parseObject(respStr);
        boolean success = returnJSON.getBoolean("success");
        if (success){
            logger.info("返回成功");
            JSONArray dataArray = returnJSON.getJSONArray("data");
            //返回成功的情况下，把返回结果合并到同步记录表中
            if (dataArray != null && dataArray.size() > 0){
                List<YstripUserHistory> list = new ArrayList<>();
                for (int i = 0;i < dataArray.size();i++){
                    JSONObject dataJSON = dataArray.getJSONObject(i);
                    int status = dataJSON.getIntValue("Status");
                    if (1 == status){
                        //如果是状态是1，说明同步成功
                        YstripUserHistory ystripUserHistory = new YstripUserHistory();
                        ystripUserHistory.setCompanyNo(dataJSON.getString("CompanyNo"));
                        ystripUserHistory.setUserNo(dataJSON.getString("UserNo"));
                        ystripUserHistory.setUserPhone(dataJSON.getString("UserPhone"));
                        ystripUserHistory.setUserName(dataJSON.getString("UserName"));
                        ystripUserHistory.setUserEmail(dataJSON.getString("UserEmail"));
                        ystripUserHistory.setCardNo(dataJSON.getString("CardNo"));
                        ystripUserHistory.setChannel(dataJSON.getString("Channel"));
                        ystripUserHistory.setRemark(dataJSON.getString("Remark"));
                        ystripUserHistory.setStatus(String.valueOf(status));
                        ystripUserHistory.setResult(dataJSON.getString("Result"));
                        ystripUserHistory.setUserId(companyNoUserNo2UserIdMap.get(
                                ystripUserHistory.getCompanyNo() + ystripUserHistory.getUserNo()));
                        list.add(ystripUserHistory);
                    }
                }
                if (list.size() > 0){
                    iYstripUserHistoryService.insertOrUpdateAllColumnBatch(list);
                }
            }

            return dataArray.toJSONString();
        }else {
            String errorMsg = returnJSON.getString("msg");
            logger.info("返回失败");
            logger.error(errorMsg);
            throw new BaseException(-100,errorMsg);
        }
    }

    @Override
    public String editUser(JSONObject userInfoJSON) {
        JSONObject reqJSON = new JSONObject();
        reqJSON.put("Channel",YStripConstant.CHANNEL);
        reqJSON.put("action",YStripConstant.USER_EDIT_ACTION);
        reqJSON.put("times",String.valueOf((int)(System.currentTimeMillis()/1000)));
        reqJSON.put("CompanyNo",userInfoJSON.getString("CompanyNo"));
        reqJSON.put("UserNo",userInfoJSON.getString("UserNo"));

        reqJSON.put("OldChannel",userInfoJSON.getString("OldChannel"));
        reqJSON.put("OldCompanyNo",userInfoJSON.getString("OldCompanyNo"));
        reqJSON.put("OldUserNo",userInfoJSON.getString("OldUserNo"));

        String sign = SHAUtil.getMD5(reqJSON.getString("Channel") + reqJSON.getString("CompanyNo")
                    + reqJSON.getString("UserNo") + reqJSON.getString("times")
                    + yStripBase.getKey());
        reqJSON.put("sign",sign);
        String reqStr = reqJSON.toJSONString();
        logger.info("云上火车票，修改用户，请求数据->" + reqStr);
        String respStr = "{}";
        try {
            respStr = Request.Post(yStripBase.getBaseUrl() + yStripBase.getUserMethod())
                    .bodyString(reqStr,ContentType.APPLICATION_JSON).execute()
                    .returnContent().asString(Charset.forName("UTF-8"));
            logger.info("云上火车票，修改用户，返回值->" + respStr);
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
            throw new BaseException(-100,e.getMessage());
        }
        JSONObject returnJSON = JSON.parseObject(respStr);
        boolean success = returnJSON.getBoolean("success");
        if (success){
            logger.info("返回成功");
            JSONArray dataArray = returnJSON.getJSONArray("data");
            return dataArray.toJSONString();
        }else {
            String errorMsg = returnJSON.getString("msg");
            logger.info("返回失败");
            logger.error(errorMsg);
            throw new BaseException(-100,errorMsg);
        }
    }

    @Override
    public String deleleUser() {
        return null;
    }

    @Override
    public String queryUser() {
        return null;
    }

    @Override
    public String ssoLogin(String jumpType, YStripUser yStripUser) {
        //check the jumpType
        if (!"SYS".equals(jumpType) && !"TH5".equals(jumpType)){
            logger.error("无效的jumpType");
            throw new BaseException(-100,"无效的跳转类型!");
        }
        StringBuffer urlBuffer = new StringBuffer();
        try {
            String times = String.valueOf((int)(System.currentTimeMillis()/1000));
            String encodedCompanyNo = URLEncoder.encode(yStripUser.getCompanyNo(),"utf-8");
            String encodedUserNo = URLEncoder.encode(yStripUser.getUserNo(),"utf-8");
            String sign = SHAUtil.getMD5(YStripConstant.CHANNEL + yStripUser.getCompanyNo()
                    + yStripUser.getUserNo() + jumpType + times + yStripBase.getKey());

            urlBuffer.append(yStripBase.getBaseUrl()).append(yStripBase.getLoginMethod())
                    .append("?").append("Channel=").append(YStripConstant.CHANNEL)
                    .append("&").append("CompanyNo=")
                    .append(encodedCompanyNo)
                    .append("&").append("UserNo=")
                    .append(encodedUserNo)
                    .append("&").append("jumptype=").append(jumpType)
                    .append("&").append("sign=").append(sign)
                    .append("&").append("times=").append(times);
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage(),e);
            throw new BaseException(-100,e.getMessage());
        }
        return urlBuffer.toString();
    }

    /**
     * 同步订单
     * @param yStripSyncOrderParam
     * @return
     */
    @Override
    public String syncOrders(YStripSyncOrderParam yStripSyncOrderParam, int channelId, String tenant){
        StringBuffer urlBuffer = new StringBuffer();
        try {
            String times = String.valueOf((int)(System.currentTimeMillis()/1000));
            String sign = SHAUtil.getMD5(YStripConstant.CHANNEL + yStripSyncOrderParam.getCompanyNo()
                    + yStripSyncOrderParam.getBeginDate()
                    + yStripSyncOrderParam.getEndDate() + times + yStripBase.getKey());

            urlBuffer.append(yStripBase.getBaseUrl() + yStripBase.getOrderMethod())
                    .append("?").append("action=query&")
                    .append("Channel=").append(YStripConstant.CHANNEL)
                    .append("&").append("CompanyNo=")
                    .append(URLEncoder.encode(yStripSyncOrderParam.getCompanyNo(),"utf-8"))
                    .append("&").append("Birthbegin=").append(yStripSyncOrderParam.getBeginDate())
                    .append("&").append("Birthend=").append(yStripSyncOrderParam.getEndDate())
                    .append("&").append("times=").append(times)
                    .append("&").append("sign=").append(sign);

            String respStr = Request.Get(urlBuffer.toString())
                    .execute().returnContent().asString(Charset.forName("UTF-8"));

            JSONObject respJSON = JSON.parseObject(respStr);
            boolean success = respJSON.getBoolean("success");
            if (success){
                JSONArray orderArray = respJSON.getJSONArray("data");
                if (orderArray != null && orderArray.size() > 0){
                    for (int i = 0;i < orderArray.size();i++){
                        JSONObject order = orderArray.getJSONObject(i);
                        dealWithMongo(order.getString("OrderNo"), YStripConstant.YSTRIP_MONGO_ORDER_TABLENAME, order);
                        order.put("channelId",channelId);
                        JSONObject res = convertService.convert(ystripTradeType, systemCode, cnvRegisterUserId, cnvRegisterTenant, cnvRegisterCookie, order);
                        if (res != null && res.getBoolean("success")) {
                            JSONArray results = res.getJSONArray("result");
                            if (results != null && results.size() > 0) {
                                for (int j = 0; j < results.size(); j++) {
                                    JSONObject jsonObject = results.getJSONObject(j);
                                    JSONObject orderCenter = JSON.parseObject(jsonObject.getString("data"));
                                    if (orderCenter != null && orderCenter.size() > 0) {
                                        String orderNo = orderCenter.getString("orderNo");
                                        String userNo = orderCenter.getString("UserNo");
                                        briOrderService.saveTrain(orderCenter,orderNo,tenant,userNo,ChannelEnum.YSTRIP.getName(),channelId);
                                    }
                                }
                            }
                        }
//                        //保存原始记录至mongodb
//                        CriteriaMap criteriaMap = new CriteriaMap();
//                        criteriaMap.put("OrderNo",order.getString("OrderNo"));
//
//                        List<JSONObject> originOrderJSONs = mongoDao.findByMap(criteriaMap,JSONObject.class,
//                                YStripConstant.YSTRIP_MONGO_ORDER_TABLENAME);
//                        if (originOrderJSONs != null && originOrderJSONs.size() > 0) {
//                            mongoDao.update(criteriaMap,order,YStripConstant.YSTRIP_MONGO_ORDER_TABLENAME);
//                        }else {
//                            mongoDao.insert(order,YStripConstant.YSTRIP_MONGO_ORDER_TABLENAME);
//                        }
//
//                        //保存进商旅服务订单表
//                        BriTrainOrder briTrainOrder = OrderConvertUtil
//                                .convertYStripOrder2BriTrainOrder(order);
//                        Wrapper<BriTrainOrder> briTrainOrderWrapper = new EntityWrapper<>();
//                        briTrainOrderWrapper.where("order_no={0}", briTrainOrder.getOrderNo());
//                        List<BriTrainOrder> briFlightOrders = briTrainOrderService.selectList(briTrainOrderWrapper);
//                        if (briFlightOrders != null && briFlightOrders.size() > 0) {
//                            briTrainOrderService.update(briTrainOrder, briTrainOrderWrapper);
//                        } else {
//                            briTrainOrderService.insert(briTrainOrder);
//                        }
                    }
                }
            }else {
                logger.error(respJSON.getString("msg"));
                throw new BaseException(-100,respJSON.getString("msg"));
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new BaseException(-100,e.getMessage());
        }

        return null;
    }

    private void dealWithMongo(String orderId, String mongoName, JSONObject orderJson) {
        CriteriaMap criteriaMap = new CriteriaMap();
        criteriaMap.put("OrderNo",orderId);
        List<JSONObject> ordersources = mongoDao.findByMap(criteriaMap, JSONObject.class, mongoName);
        if(ordersources != null && ordersources.size() > 0) {
            mongoDao.deleteByMap(criteriaMap, mongoName);
            mongoDao.getMongoTemplate().save(orderJson, mongoName);
        }
        else {
            mongoDao.getMongoTemplate().insert(orderJson, mongoName);
        }
    }
}
